package com.maiko.maikoaiagent.rag;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.markdown.MarkdownDocumentReader;
import org.springframework.ai.reader.markdown.config.MarkdownDocumentReaderConfig;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 批量加载项目资源路径下的Markdown文件并将其解析为AI可用的Document对象列表，常用于大模型的文档问答、知识库等功能。
 * @author: Maiko7
 * @create: 2025-06-15 14:49
 */
// 将此类注册为Spring Bean
@Component
// 自动生成log日志对象，便于日志输出。
@Slf4j
class LoveAppDocumentLoader {

    // 用于按模式（如 "classpath:document/*.md"）读取多个资源文件（比如 Markdown 文档）。
    private final ResourcePatternResolver resourcePatternResolver;

    // Spring会自动注入ResourcePatternResolver实例，供文件搜索用。
    LoveAppDocumentLoader(ResourcePatternResolver resourcePatternResolver) {
        this.resourcePatternResolver = resourcePatternResolver;
    }

    /**
     * 用于批量读取并解析resources/document/目录下的所有.md文件为Document对象
     * @return
     */
    public List<Document> loadMarkdowns() {
        List<Document> allDocuments = new ArrayList<>();
        try {
            // 这里可以修改为你要加载的多个 Markdown 文件的路径模式
            // 使用通配符加载所有 classpath:document/目录下的.md文件。
            Resource[] resources = resourcePatternResolver.getResources("classpath:document/*.md");
            // 遍历每一个Markdown文件资源
            for (Resource resource : resources) {
                // 读取文件名作为元数据。
                String fileName = resource.getFilename();
                /**
                 * 提取文档倒数第3和第2个字作为标签
                 * 它这个什么意思呢，你看resource中的document你看那个-单身篇；-已婚篇；-恋爱篇。它其实就是提取这个
                 */
                String status = fileName.substring(fileName.length() - 6, fileName.length() - 4);
                // 配置 Markdown 解析行为
                MarkdownDocumentReaderConfig config = MarkdownDocumentReaderConfig.builder()
                        .withHorizontalRuleCreateDocument(true)     // 遇到 --- 分割线会视为一篇新的文档
                        .withIncludeCodeBlock(false)        // 不包含代码块内容
                        .withIncludeBlockquote(false)       // 不包含引用内容
                        .withAdditionalMetadata("filename", fileName)   // 将文件名添加为文档元数据
                        .withAdditionalMetadata("status", status)   // 将标签添加为文档元数据
                        .build();
                // 创建一个MarkdownDocumentReader解析器，将文件内容解析为多个 Document 实例，并加入到 allDocuments 结果列表中。
                MarkdownDocumentReader reader = new MarkdownDocumentReader(resource, config);
                allDocuments.addAll(reader.get());
            }
        } catch (IOException e) {
            log.error("Markdown 文档加载失败", e);
        }
        // 返回所有Markdown文档解析后的Document对象，供后续AI模型使用
        return allDocuments;
    }
}
